from time import time

from sqlalchemy import desc

from app import app
from core.utils.auto_id import AutoID
from core.utils.configure import Configure


class BaseEntity(object):
    db = app.db
    id = db.Column(db.BigInteger, primary_key=True)
    app_id = db.Column(db.String(15))
    created_time = db.Column(db.String(12))
    updated_time = db.Column(db.String(12))
    status = db.Column(db.Integer, default=1)
    is_del = db.Column(db.Integer, default=0)
    sort = db.Column(db.Integer, default=1)

    @classmethod
    def select(cls, fields=None, **kwargs):
        if fields is None:
            fields = ['name']
        default_condition = {'is_del': 0, 'app_id': Configure().get('X_APP_ID')}
        where = kwargs['where'] if 'where' in kwargs.keys() and kwargs['where'] else {}
        order = kwargs['order'] if 'order' in kwargs.keys() and kwargs['order'] else 'id'
        page = 1
        size = 100
        if 'page' in kwargs.keys():
            page = int(kwargs['page'])
            del kwargs['page']
        if 'size' in kwargs.keys():
            size = int(kwargs['size'])
            del kwargs['size']

        condition = dict(default_condition, **where)
        return (
            cls.query.filter_by(**condition)
            .order_by(desc(order))
            .offset(int(page - 1) * size)
            .limit(size)
            .all()
        )

    @classmethod
    def count(cls, **kwargs):
        default_condition = {'is_del': 0, 'app_id': Configure().get('X_APP_ID')}
        condition = dict(default_condition, **kwargs)
        return cls.query.filter_by(**condition).count()

    @classmethod
    def get(cls, **kwargs):
        default_condition = {'is_del': 0, 'app_id': Configure().get('X_APP_ID')}
        condition = dict(default_condition, **kwargs)
        return cls.query.filter_by(**condition).all()

    @classmethod
    def create(cls, **kwargs):
        default_field = {
            'id': AutoID().get_last_insert_id(),
            'created_time': str(int(time())),
            'updated_time': str(int(time())),
            'app_id': Configure().get('X_APP_ID'),
            'status': 1,
            'is_del': 0,
            'sort': 1,
        }
        fields = dict(default_field, **kwargs)
        cls(**fields).save()
        return default_field['id']

    def update(self, commit=True, **kwargs):
        for attr, value in kwargs.items():
            setattr(self, attr, value)
            setattr(self, 'updated_time', str(int(time())))
        return commit and self.save() or self

    def save(self, commit=True):
        self.db.session.add(self)
        return commit and self.db.session.commit() or self
